背包公钥算法

背包加密分为加法背包和乘法背包。

1、加法背包:我们知道,1<2,1+2<4,1+2+4<8,1+2+4+8<16,……,那么如果我们选择这样一些数,这些数从小到大排列,如果前面所有的数加起来的值总小于后面的数,那么这些数就可以构成一个背包,我们给一个这个背包里面的某些数的和,这个数就是被加密的数,由这个背包组成这个数只有一种组合方式,这个方式就是秘密了,例如给大家一个封包(236122448),由这个背包里的某些数构成的数:86,你知道86怎么来的吗?当然,你看着背包里面的内容,可以知道是由2+12+24+48得到的,如果你没有这个背包,而是直接得到这个86,你知道组成这个86的最小的数是多少吗?你无法知道,因为加起来等于86的数非常多:85+1=8684+2=86等等,你是无法知道的,所以,背包加密非常难破。

2、乘法背包:乘法背包比加法背包更复杂,不仅是运算量大了很多,更重要的是你得到的一个被加密了的数据更大,一般都是上亿的,而且在许多机密的机关里面,背包的数据都不是有这个单位,而是用位。我们知道,1<2,1*2<3,1*2*3<7,1*2*3*7<43,1*2*3*7*42<1765,数字的增长还是很快的,之所以复杂,就是因为数字很大啊!背包的特点是:如果背包里面的数据按小到大排列,那么,前面所有数据的乘积小于后面的任何一个元素,这个就是背包的特点,是不是很简单,但是要知道乘积的数字的增长是非常快的!

 

应用领域:

很多数据都需要加密,例如银行的数据、网络游戏、军事机构、行政机构以及其他重要场所。不过虽然这种加密效果非常好,但是加密的程度太大也不现实,一般不会有非常复杂的加密,如果一个数据就几百位,而且还用非常规进制,那么可以想象电脑要算多久啊,会多么影响速度啊!



公钥算法之背包算法

这是一个非对称算法,即可生成多个不同的公钥,分发给其他人,然后其他人用各自的公钥加密文件,而算法只生成一个私钥(自己保存),这私钥可解密不同公钥加密的文件。在不知道私钥的前提下,破解文件是一个NP难问题。

下面贴上高老师的讲义:

1.背包算法基于背包问题的简化版,即子集和问题( Subset sum)。
2.子集和问题:给定一个整数集 A(俗称为背包)和整数 b,要求找出 A的一个子集,使得其中元素之和等于 b
3.子集和问题是 NP完全问题。然而若集合 A是一个超级增长序列( Superincreasing),则可以使用简单的贪婪策略在多项式时间求解。
4.超级增长序列指集合中后一个元素大于前面所有元素之和。如 {2, 7, 11, 21, 42, 89, 180, 354}。
 
算法流程:
选择一个超级增长序列 w  = ( w 1,  w 2, ...,  wn ,以及一个随机数 q  ,满足 q  >   w ,以及另一个随机数 r,使得 qr互素,即 gcd( r , q ) = 1 
 
公钥计算:算集合 β   = ( β 1,  β 2, ...,  β n) ,其中β i = (  r   ×   w i ) mod q,公钥就是  β,私钥就是 ( w q r )
 
加密:给定 n位二进制信息α  = ( α 1,  α 2, ...,  α n), 利用公钥β   = ( β 1,  β 2, ...,  β n)计算如下:  C=  ∑α i * β i , C即密文
 
解密:解密的关键是利用 ( w q r )求出的逆元 s  。此即求解方程: s*r  mod  q =1。即满足 sr  =  kq  + 1 。由于 gcd( r , q )=1,所以可以使用扩展欧几里德算法找出  s  和  k  。

附上自己的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*该程序加解密文本长度最多为16个二进制位(包括16字节),即2字节*/
#include <stdio.h>
#define N 30
bool  text[N],detext[N]; //储存待加密文本和解密文本
int  n,pubkey[N]; //公钥β
int  w[N]; //超级增长序列
 
typedef  struct  Tri //三元组结构体
{
     int  d,x,y;
}Tri;
 
Tri Extend_Euclid( int  a, int  b) //扩展欧几里德算法
{
     Tri t1,t2;
     if (b==0)
     {
         t1.d=a,t1.x=1,t1.y=0; //(a,1,0)
         return  t1;
     }
//(d,x,y)←(d',y',x'-a/b*y')
     t2=Extend_Euclid(b,a%b);
     t1.d=t2.d;
     t1.x=t2.y;
     t1.y=t2.x-a/b*t2.y;
     return  t1;
}
 
void  Create_Super_Growth() //创建超级增长序列
{
     int  i,sum=0;
     for (w[0]=1,i=1;i<N;i++)
         sum+=w[i-1]+1,w[i]=sum;
     return  ;
}
 
int  Encode( int  q, int  r) //加密
{
     int  i,c=0;
     printf ( "公钥序列:\n" );
     for (i=0;i<n;i++) //计算公钥β
     {
         pubkey[i]=w[i]*r%q;
         printf ( "%d: %d\n" ,i,pubkey[i]);
     }
     for (i=0;i<n;i++) //加密文本
         c=(c+text[i]*pubkey[i])%q;
     return  c;
}
 
void  Decode( int  q, int  r, int  c) //解密
{
     int  i;
     __int64  k,s; //防止k=c*s%q结果溢出
     Tri t;
     for (i=0;i<n;i++) detext[i]=0;
     t=Extend_Euclid(r,q); //扩展欧几里德求r逆元
     s=t.x;
     while (s<0) s+=q; //把负逆元转换为正逆元
     printf ( "r逆元:%d\n" ,s);
//开始解密
     k=s*c%q;
     printf ( "k=%d\n" ,k);
     for (i=n-1;i>=0;i--) //贪心策略解子集合问题,解密出二进制文本
         if (k>=w[i]) k-=w[i],detext[i]++;
     return  ;
}
 
int  main()
{ //随机选择q和r,q>w序列1到n范围内元素之和,q和r要互素
     int  i,c,q=0,r; //r为乘数,q为模数
     Tri t;
     Create_Super_Growth(); //创建超级增长序列
     for (i=0;i<16;i++) //假设q=w[0]+...+w[15]+1,即加密长度不超过16byte
         q+=w[i];
     q++;
     for (i=2;;i++) //寻找第一个与q互数r(不一定要第一个)
     {
         t=Extend_Euclid(q,i);
         if (t.d==1) {r=i; break ;}
     }
//  freopen("公钥算法之背包算法.txt","r",stdin);
     while ( scanf ( "%d" ,&n)!=EOF)
     {
         for (i=0;i<n;i++)
             scanf ( "%d" ,&text[i]); //二进制待加密文本
         c=Encode(q,r); //加密,得到密文
         printf ( "密文:%d\n" ,c);
         Decode(q,r,c); //解密
         printf ( "解密后文本:\n" );
         for (i=0;i<n;i++)
             printf ( "%d " ,detext[i]);
         printf ( "\n" );
     }
     return  0;
}

 样例输入:

16 1 0 0 1 1 0 1 0 1 1 1 0 0 1 1 0

样例输出:
公钥序列:
0: 3
1: 6
2: 15
3: 33
4: 69
5: 141
6: 285
7: 573
8: 1149
9: 2301
10: 4605
11: 9213
12: 18429
13: 36861
14: 73725
15: 49165
密文:20743
r逆元:32763
k=39677
解密后文本:
1 0 0 1 1 0 1 0 1 1 1 0 0 1 1 0

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值